﻿using Framework.EncryptionService.Inteface;

namespace Framework.EncryptionService.Abstract
{
    /// <summary>
    /// 加密服务抽象类
    /// </summary>
    public abstract class AbstractEncryptionServiceHelps<M> : IEncryptionServiceHelps where M: AbstractEncryptionServiceHelps<M>,new ()
    {
        /// <summary>
        /// 加密服务
        /// </summary>
        /// <param name="encryption">加密服务秘钥实体（一次性）</param>
        public AbstractEncryptionServiceHelps(EncryptionServiceHelpsEntity encryption = null)
        {
            if (encryption != null)
            {
                DisposableEncryption = encryption;
                if (Encryption == null)
                {
                    Encryption = encryption;
                }
            }

            if (Encryption == null)
            {
                Encryption = InitEncryption();
            }
        }

        /// <summary>
        /// 一次性秘钥实体
        /// </summary>
        private readonly EncryptionServiceHelpsEntity DisposableEncryption;

        /// <summary>
        /// 每个派生类独立的全局秘钥实体
        /// </summary>
        private static EncryptionServiceHelpsEntity Encryption;

        /// <summary>
        /// 获取当前使用的秘钥实体
        /// </summary>
        private EncryptionServiceHelpsEntity CurrentEncryption
        {
            get
            {
                return DisposableEncryption ?? Encryption;
            }
        }
        /// <summary>
        /// 私钥
        /// </summary>
        protected string PrivateSecretKey
        {
            get
            {
                return CurrentEncryption?.PrivateSecretKey;
            }
        }

        /// <summary>
        /// 公钥 or 向量
        /// </summary>
        protected string PublicSecretKey
        {
            get
            {
                return CurrentEncryption?.PublicSecretKey;
            }
        }

        /// <summary>
        /// 获取公钥 or 向量
        /// </summary>
        /// <returns></returns>
        public string GetPublicSecretKey()
        {
            return PublicSecretKey;
        }

        /// <summary>
        /// 获取私钥
        /// </summary>
        /// <returns></returns>
        public string GetPrivateSecretKey()
        {
            return PrivateSecretKey;
        }

        /// <summary>
        /// 初始化秘钥
        /// </summary>
        /// <returns></returns>
        public abstract EncryptionServiceHelpsEntity InitEncryption();

        public abstract byte[] Encrypt(string data);

        public virtual string Encrypt<T>(T data) where T : class, new()
        {
            byte[] byte_ = Encrypt(data.ConvertToString());
            return byte_.ToBase64String();
        }


        public virtual T Decrypt<T>(string ciphertext)
        {
            return DecryptToString(ciphertext.FromBase64String()).ConvertToObject<T>();
        }


        public virtual T Decrypt<T>(byte[] ciphertext)
        {
            return DecryptToString(ciphertext).ConvertToObject<T>();
        }


        public virtual string Decrypt(string ciphertext)
        {
            return DecryptToString(ciphertext.FromBase64String());
        }

        public abstract byte[] Decrypt(byte[] encryptedBytes);

        public virtual string DecryptToString(byte[] encryptedBytes)
        {
            return Decrypt(encryptedBytes).ConvertToString();
        }
    }
}
